using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.EditorTools;

namespace TCC.Framework.Tools
{
    [EditorTool("AxisTool", typeof(Transform))]
    public class AxisTool : EditorTool
    {
        private GUIContent uIContent;
        private Transform _target;
        private List<Transform> chlids = new List<Transform>();
        private Axis axis = Axis.X;
        private GUIContent centerConter;

        public GUIContent CenterConter
        {
            get
            {
                if (centerConter == null)
                {
                    centerConter = new GUIContent();
                    centerConter.image = EditorGUIUtility.IconContent("Grid.MoveTool").image;
                    centerConter.tooltip = "居中所有轴";

                }
                return centerConter;
            }
        }
        public override GUIContent toolbarIcon
        {
            get
            {
                if (uIContent == null)
                {
                    uIContent = new GUIContent();
                    uIContent.tooltip = "AxisTool";
                    uIContent.image = EditorGUIUtility.IconContent("AvatarPivot").image;
                }
                return uIContent;
            }
        }

        private void OnEnable()
        {
            EditorTools.activeToolChanged += TargetChangeEvent;
            Selection.selectionChanged += TargetChangeEvent;
        }

        private void TargetChangeEvent()
        {
            if (!EditorTools.IsActiveTool(this))
                return;
            _target = target as Transform;
            chlids.Clear();
            foreach (Transform item in _target)
            {
                chlids.Add(item);
            }
        }

        private void OnDisable()
        {
            EditorTools.activeToolChanged -= TargetChangeEvent;
            Selection.selectionChanged -= TargetChangeEvent;
        }

        public override void OnToolGUI(EditorWindow window)
        {
            if (_target == null) return;

            Rect rect = new Rect(window.position.width - 200, window.position.height - 170, 160, 50);
            int id = GUIUtility.GetControlID(FocusType.Passive, rect);
            HandleUtility.AddDefaultControl(id);
            using (new Handles.DrawingScope())
            {
                EditorGUI.BeginChangeCheck();
                Vector3 newPos = Handles.PositionHandle(_target.position, Quaternion.identity);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(_target, "Move Pivot");
                    Vector3 dir = newPos - _target.position;
                    _target.position = newPos;
                    for (int i = 0; i < chlids.Count; i++)
                    {
                        Undo.RecordObject(chlids[i], "Move Pivot");
                        chlids[i].position -= dir;
                    }
                }
            }
            Handles.BeginGUI();
            GUI.Box(rect, "", "Window");
            rect.Set(rect.x + 3, rect.y + 3, 20, 20);
            GUI.Label(rect, "轴");
            rect.Set(rect.x + 20, rect.y + 1, 80, 20);
            axis = (Axis)EditorGUI.EnumPopup(rect, axis);
            rect.Set(rect.x + 80, rect.y - 1, 20, 20);
            if (GUI.Button(rect, CenterConter))
            {
                SetAxis(2);
            }
            rect.Set(rect.x - 100, rect.y + 23, 50, 20);
            if (GUI.Button(rect, axis == Axis.Y ? "上" : (axis == Axis.X ? "左" : "前")))
            {
                SetAxis(-1);
            }
            rect.Set(rect.x + 50, rect.y, 50, 20);
            if (GUI.Button(rect, "中"))
            {
                SetAxis(0);
            }
            rect.Set(rect.x + 50, rect.y, 50, 20);
            if (GUI.Button(rect, axis == Axis.Y ? "下" : (axis == Axis.X ? "右" : "后")))
            {
                SetAxis(1);
            }
            GUI.enabled = true;
            Handles.EndGUI();
        }

        void SetAxis(int pos)
        {
            Bounds bounds = GetBounds(_target);
            if (pos == 2)
            {
                _target.position += bounds.center;
                foreach (Transform item in _target)
                {
                    item.position -= bounds.center;
                }
                return;
            }
            float value = 0;
            switch (axis)
            {
                case Axis.X:
                    value = pos == -1 ? bounds.center.x + bounds.size.x / 2 : (pos == 0 ? bounds.center.x : bounds.center.x - bounds.size.x / 2);
                    _target.position = new Vector3(_target.position.x + value, _target.position.y, _target.position.z);
                    foreach (Transform item in _target)
                    {
                        item.position = new Vector3(item.position.x - value, item.position.y, item.position.z);
                    }
                    break;
                case Axis.Y:
                    value = pos == -1 ? bounds.center.y + bounds.size.y / 2 : (pos == 0 ? bounds.center.y : bounds.center.y - bounds.size.y / 2);
                    _target.position = new Vector3(_target.position.x, _target.position.y + value, _target.position.z);
                    foreach (Transform item in _target)
                    {
                        item.position = new Vector3(item.position.x, item.position.y - value, item.position.z);
                    }
                    break;
                case Axis.Z:
                    value = pos == -1 ? bounds.center.z + bounds.size.z / 2 : (pos == 0 ? bounds.center.z : bounds.center.z - bounds.size.z / 2);
                    _target.position = new Vector3(_target.position.x, _target.position.y, _target.position.z + value);
                    foreach (Transform item in _target)
                    {
                        item.position = new Vector3(item.position.x, item.position.y, item.position.z - value);
                    }
                    break;
            }
        }

        Bounds GetBounds(Transform target)
        {
            Renderer[] renders = target.GetComponentsInChildren<Renderer>();
            Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
            if (renders.Length == 0) return bounds;

            Vector3 postion = target.position;
            Quaternion rotation = target.rotation;
            Vector3 scale = target.localScale;
            target.position = Vector3.zero;
            target.localScale = Vector3.one;

            Vector3 center = Vector3.zero;

            foreach (Renderer child in renders)
            {
                center += child.bounds.center;
            }
            center /= renders.Length;
            bounds.center = center;
            foreach (Renderer child in renders)
            {
                bounds.Encapsulate(child.bounds);
            }

            target.position = postion;
            target.localScale = scale;

            return bounds;
        }

        enum Axis
        {
            X,
            Y,
            Z
        }
    }
}
